package org.linlinjava.litemall.admin.job;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.linlinjava.litemall.admin.constant.LitemallAdminConstants;
import org.linlinjava.litemall.admin.task.ScheduledCronTaskRegistrar;
import org.linlinjava.litemall.core.notify.NoticeHelper;
import org.linlinjava.litemall.core.util.AdminCouponDateUtil;
import org.linlinjava.litemall.db.beans.Constants;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.service.LitemallUserService;
import org.linlinjava.litemall.db.service.LumiereCouponService;
import org.linlinjava.litemall.db.service.LumiereCouponStrategyService;
import org.linlinjava.litemall.db.service.LumiereCouponUserService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.MonthDay;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
@Slf4j
public class AdminStrategyJob implements Job {

    private final LumiereCouponUserService lumiereCouponUserService;

    private final LumiereCouponStrategyService lumiereCouponStrategyService;

    private final LitemallUserService litemallUserService;

    private final NoticeHelper noticeHelper;
    private final ScheduledCronTaskRegistrar scheduledCronTaskRegistrar;


    //@Scheduled(cron = "0 0 0 * * ?")
    @Transactional
    public void birthdayCouponJob(){
        log.info("系统开启任务检查生日优惠券发放");
        //查找是否有开启的生日策略
        List<LumiereCouponStrategy> lumiereCouponStrategies = lumiereCouponStrategyService.list(Wrappers.lambdaQuery(LumiereCouponStrategy.class)
                .eq(LumiereCouponStrategy::getCouponType, 4)
                .eq(LumiereCouponStrategy::getStatus, 1)
                .eq(LumiereCouponStrategy::getDeleted, 0));
        if(CollUtil.isEmpty(lumiereCouponStrategies)){return;}
        //获取当天所有过生日的用户
        List<LitemallUser> litemallUserList = litemallUserService.list(Wrappers.lambdaQuery(LitemallUser.class).isNotNull(LitemallUser::getBirthday));
        LocalDate currentDate = LocalDate.now();
        List<LitemallUser> birthdayUser = litemallUserList.stream().filter(litemallUser -> {
            MonthDay monthDay = MonthDay.from(litemallUser.getBirthday());
            MonthDay nowMonthDay = MonthDay.from(currentDate);
            return monthDay.equals(nowMonthDay);
        }).collect(Collectors.toList());
        if(CollUtil.isEmpty(litemallUserList)){return;}
        CompletableFuture.runAsync(()->{
            Lock lock =new ReentrantLock();
            try {
                //发放优惠券 所有是生日福利的券 生日券无限发放
                for (LitemallUser litemallUser : birthdayUser) {
                    for (LumiereCouponStrategy lumiereCouponStrategy : lumiereCouponStrategies) {
                        lock.lock();
                        long nextId = IdUtil.getSnowflake(2, 2).nextId();
                        LocalDateTime[] localDateTimes = AdminCouponDateUtil.calculateExpirationTime(lumiereCouponStrategy);
                        //发放券
                        LumiereCouponUser coupon = LumiereCouponUser.builder()
                                .userId(litemallUser.getId())
                                .strategyId(lumiereCouponStrategy.getId())
                                .couponId(lumiereCouponStrategy.getCouponId())
                                .userName(litemallUser.getUsername())
                                .startTime(localDateTimes[0])
                                .endTime(localDateTimes[1])
                                .code(String.valueOf(nextId))
                                .addTime(LocalDateTime.now())
                                .updateTime(LocalDateTime.now())
                                .deleted(false)
                                .build();
                        lumiereCouponUserService.save(coupon);
                        //发放福利券消息
                        noticeHelper.noticeUser( Constants.MSG_TYPE_OTHER, LitemallAdminConstants.ADMIN_COUPON_BIRTHDAY_USER_TITLE,String.format(LitemallAdminConstants.ADMIN_COUPON_BIRTHDAY_USER_NOTICEHELPER,litemallUser.getNickname()),litemallUser.getId(),lumiereCouponStrategies);
                        lock.unlock();
                    }
                }
            }catch (Exception e){
                lock.unlock();
            }finally {
                lock.unlock();
            }
        });
    }


    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        this.birthdayCouponJob();
        scheduledCronTaskRegistrar.scheduleJobLog(jobExecutionContext);
    }
}
